; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc -mtriple=ve-unknown-unknown < %s | FileCheck %s

define i8 @atomicrmw_uinc_wrap_i8(ptr %ptr, i8 %val) {
; CHECK-LABEL: atomicrmw_uinc_wrap_i8:
; CHECK:       # %bb.0:
; CHECK-NEXT:    and %s3, %s1, (32)0
; CHECK-NEXT:    fencem 3
; CHECK-NEXT:    and %s1, -4, %s0
; CHECK-NEXT:    and %s0, 3, %s0
; CHECK-NEXT:    sla.w.sx %s0, %s0, 3
; CHECK-NEXT:    sla.w.sx %s2, (56)0, %s0
; CHECK-NEXT:    ldl.sx %s4, (, %s1)
; CHECK-NEXT:    xor %s2, -1, %s2
; CHECK-NEXT:    and %s2, %s2, (32)0
; CHECK-NEXT:    and %s3, %s3, (56)0
; CHECK-NEXT:  .LBB0_1: # %atomicrmw.start
; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
; CHECK-NEXT:    or %s5, 0, %s4
; CHECK-NEXT:    and %s4, %s5, (32)0
; CHECK-NEXT:    srl %s4, %s4, %s0
; CHECK-NEXT:    and %s6, %s4, (56)0
; CHECK-NEXT:    adds.w.sx %s4, 1, %s4
; CHECK-NEXT:    cmpu.w %s6, %s6, %s3
; CHECK-NEXT:    cmov.w.ge %s4, (0)1, %s6
; CHECK-NEXT:    and %s4, %s4, (56)0
; CHECK-NEXT:    sla.w.sx %s4, %s4, %s0
; CHECK-NEXT:    and %s6, %s5, %s2
; CHECK-NEXT:    or %s4, %s6, %s4
; CHECK-NEXT:    cas.w %s4, (%s1), %s5
; CHECK-NEXT:    brne.w %s4, %s5, .LBB0_1
; CHECK-NEXT:  # %bb.2: # %atomicrmw.end
; CHECK-NEXT:    and %s1, %s4, (32)0
; CHECK-NEXT:    srl %s0, %s1, %s0
; CHECK-NEXT:    fencem 3
; CHECK-NEXT:    b.l.t (, %s10)
  %result = atomicrmw uinc_wrap ptr %ptr, i8 %val seq_cst
  ret i8 %result
}

define i16 @atomicrmw_uinc_wrap_i16(ptr %ptr, i16 %val) {
; CHECK-LABEL: atomicrmw_uinc_wrap_i16:
; CHECK:       # %bb.0:
; CHECK-NEXT:    and %s3, %s1, (32)0
; CHECK-NEXT:    fencem 3
; CHECK-NEXT:    and %s1, -4, %s0
; CHECK-NEXT:    and %s0, 3, %s0
; CHECK-NEXT:    sla.w.sx %s0, %s0, 3
; CHECK-NEXT:    sla.w.sx %s2, (48)0, %s0
; CHECK-NEXT:    ldl.sx %s4, (, %s1)
; CHECK-NEXT:    xor %s2, -1, %s2
; CHECK-NEXT:    and %s2, %s2, (32)0
; CHECK-NEXT:    and %s3, %s3, (48)0
; CHECK-NEXT:  .LBB1_1: # %atomicrmw.start
; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
; CHECK-NEXT:    or %s5, 0, %s4
; CHECK-NEXT:    and %s4, %s5, (32)0
; CHECK-NEXT:    srl %s4, %s4, %s0
; CHECK-NEXT:    and %s6, %s4, (48)0
; CHECK-NEXT:    adds.w.sx %s4, 1, %s4
; CHECK-NEXT:    cmpu.w %s6, %s6, %s3
; CHECK-NEXT:    cmov.w.ge %s4, (0)1, %s6
; CHECK-NEXT:    and %s4, %s4, (48)0
; CHECK-NEXT:    sla.w.sx %s4, %s4, %s0
; CHECK-NEXT:    and %s6, %s5, %s2
; CHECK-NEXT:    or %s4, %s6, %s4
; CHECK-NEXT:    cas.w %s4, (%s1), %s5
; CHECK-NEXT:    brne.w %s4, %s5, .LBB1_1
; CHECK-NEXT:  # %bb.2: # %atomicrmw.end
; CHECK-NEXT:    and %s1, %s4, (32)0
; CHECK-NEXT:    srl %s0, %s1, %s0
; CHECK-NEXT:    fencem 3
; CHECK-NEXT:    b.l.t (, %s10)
  %result = atomicrmw uinc_wrap ptr %ptr, i16 %val seq_cst
  ret i16 %result
}

define i32 @atomicrmw_uinc_wrap_i32(ptr %ptr, i32 %val) {
; CHECK-LABEL: atomicrmw_uinc_wrap_i32:
; CHECK:       # %bb.0:
; CHECK-NEXT:    fencem 3
; CHECK-NEXT:    ldl.sx %s2, (, %s0)
; CHECK-NEXT:    and %s1, %s1, (32)0
; CHECK-NEXT:  .LBB2_1: # %atomicrmw.start
; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
; CHECK-NEXT:    or %s3, 0, %s2
; CHECK-NEXT:    adds.w.sx %s2, 1, %s2
; CHECK-NEXT:    cmpu.w %s4, %s3, %s1
; CHECK-NEXT:    cmov.w.ge %s2, (0)1, %s4
; CHECK-NEXT:    cas.w %s2, (%s0), %s3
; CHECK-NEXT:    brne.w %s2, %s3, .LBB2_1
; CHECK-NEXT:  # %bb.2: # %atomicrmw.end
; CHECK-NEXT:    fencem 3
; CHECK-NEXT:    or %s0, 0, %s2
; CHECK-NEXT:    b.l.t (, %s10)
  %result = atomicrmw uinc_wrap ptr %ptr, i32 %val seq_cst
  ret i32 %result
}

define i64 @atomicrmw_uinc_wrap_i64(ptr %ptr, i64 %val) {
; CHECK-LABEL: atomicrmw_uinc_wrap_i64:
; CHECK:       # %bb.0:
; CHECK-NEXT:    fencem 3
; CHECK-NEXT:    ld %s2, (, %s0)
; CHECK-NEXT:  .LBB3_1: # %atomicrmw.start
; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
; CHECK-NEXT:    or %s3, 0, %s2
; CHECK-NEXT:    lea %s2, 1(, %s2)
; CHECK-NEXT:    cmpu.l %s4, %s3, %s1
; CHECK-NEXT:    cmov.l.ge %s2, (0)1, %s4
; CHECK-NEXT:    cas.l %s2, (%s0), %s3
; CHECK-NEXT:    brne.l %s2, %s3, .LBB3_1
; CHECK-NEXT:  # %bb.2: # %atomicrmw.end
; CHECK-NEXT:    fencem 3
; CHECK-NEXT:    or %s0, 0, %s2
; CHECK-NEXT:    b.l.t (, %s10)
  %result = atomicrmw uinc_wrap ptr %ptr, i64 %val seq_cst
  ret i64 %result
}

define i8 @atomicrmw_udec_wrap_i8(ptr %ptr, i8 %val) {
; CHECK-LABEL: atomicrmw_udec_wrap_i8:
; CHECK:       # %bb.0:
; CHECK-NEXT:    and %s1, %s1, (32)0
; CHECK-NEXT:    fencem 3
; CHECK-NEXT:    and %s2, -4, %s0
; CHECK-NEXT:    and %s0, 3, %s0
; CHECK-NEXT:    sla.w.sx %s0, %s0, 3
; CHECK-NEXT:    sla.w.sx %s3, (56)0, %s0
; CHECK-NEXT:    ldl.sx %s5, (, %s2)
; CHECK-NEXT:    xor %s3, -1, %s3
; CHECK-NEXT:    and %s3, %s3, (32)0
; CHECK-NEXT:    and %s4, %s1, (56)0
; CHECK-NEXT:  .LBB4_1: # %atomicrmw.start
; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
; CHECK-NEXT:    or %s6, 0, %s5
; CHECK-NEXT:    and %s5, %s6, (32)0
; CHECK-NEXT:    srl %s5, %s5, %s0
; CHECK-NEXT:    and %s7, %s5, (56)0
; CHECK-NEXT:    adds.w.sx %s5, -1, %s5
; CHECK-NEXT:    cmpu.w %s34, %s7, %s4
; CHECK-NEXT:    cmov.w.gt %s5, %s1, %s34
; CHECK-NEXT:    cmov.w.eq %s5, %s1, %s7
; CHECK-NEXT:    and %s5, %s5, (56)0
; CHECK-NEXT:    sla.w.sx %s5, %s5, %s0
; CHECK-NEXT:    and %s7, %s6, %s3
; CHECK-NEXT:    or %s5, %s7, %s5
; CHECK-NEXT:    cas.w %s5, (%s2), %s6
; CHECK-NEXT:    brne.w %s5, %s6, .LBB4_1
; CHECK-NEXT:  # %bb.2: # %atomicrmw.end
; CHECK-NEXT:    and %s1, %s5, (32)0
; CHECK-NEXT:    srl %s0, %s1, %s0
; CHECK-NEXT:    fencem 3
; CHECK-NEXT:    b.l.t (, %s10)
  %result = atomicrmw udec_wrap ptr %ptr, i8 %val seq_cst
  ret i8 %result
}

define i16 @atomicrmw_udec_wrap_i16(ptr %ptr, i16 %val) {
; CHECK-LABEL: atomicrmw_udec_wrap_i16:
; CHECK:       # %bb.0:
; CHECK-NEXT:    and %s1, %s1, (32)0
; CHECK-NEXT:    fencem 3
; CHECK-NEXT:    and %s2, -4, %s0
; CHECK-NEXT:    and %s0, 3, %s0
; CHECK-NEXT:    sla.w.sx %s0, %s0, 3
; CHECK-NEXT:    sla.w.sx %s3, (48)0, %s0
; CHECK-NEXT:    ldl.sx %s5, (, %s2)
; CHECK-NEXT:    xor %s3, -1, %s3
; CHECK-NEXT:    and %s3, %s3, (32)0
; CHECK-NEXT:    and %s4, %s1, (48)0
; CHECK-NEXT:  .LBB5_1: # %atomicrmw.start
; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
; CHECK-NEXT:    or %s6, 0, %s5
; CHECK-NEXT:    and %s5, %s6, (32)0
; CHECK-NEXT:    srl %s5, %s5, %s0
; CHECK-NEXT:    and %s7, %s5, (48)0
; CHECK-NEXT:    adds.w.sx %s5, -1, %s5
; CHECK-NEXT:    cmpu.w %s34, %s7, %s4
; CHECK-NEXT:    cmov.w.gt %s5, %s1, %s34
; CHECK-NEXT:    cmov.w.eq %s5, %s1, %s7
; CHECK-NEXT:    and %s5, %s5, (48)0
; CHECK-NEXT:    sla.w.sx %s5, %s5, %s0
; CHECK-NEXT:    and %s7, %s6, %s3
; CHECK-NEXT:    or %s5, %s7, %s5
; CHECK-NEXT:    cas.w %s5, (%s2), %s6
; CHECK-NEXT:    brne.w %s5, %s6, .LBB5_1
; CHECK-NEXT:  # %bb.2: # %atomicrmw.end
; CHECK-NEXT:    and %s1, %s5, (32)0
; CHECK-NEXT:    srl %s0, %s1, %s0
; CHECK-NEXT:    fencem 3
; CHECK-NEXT:    b.l.t (, %s10)
  %result = atomicrmw udec_wrap ptr %ptr, i16 %val seq_cst
  ret i16 %result
}

define i32 @atomicrmw_udec_wrap_i32(ptr %ptr, i32 %val) {
; CHECK-LABEL: atomicrmw_udec_wrap_i32:
; CHECK:       # %bb.0:
; CHECK-NEXT:    fencem 3
; CHECK-NEXT:    ldl.sx %s2, (, %s0)
; CHECK-NEXT:    and %s1, %s1, (32)0
; CHECK-NEXT:  .LBB6_1: # %atomicrmw.start
; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
; CHECK-NEXT:    or %s3, 0, %s2
; CHECK-NEXT:    adds.w.sx %s2, -1, %s2
; CHECK-NEXT:    cmpu.w %s4, %s3, %s1
; CHECK-NEXT:    cmov.w.gt %s2, %s1, %s4
; CHECK-NEXT:    cmov.w.eq %s2, %s1, %s3
; CHECK-NEXT:    cas.w %s2, (%s0), %s3
; CHECK-NEXT:    brne.w %s2, %s3, .LBB6_1
; CHECK-NEXT:  # %bb.2: # %atomicrmw.end
; CHECK-NEXT:    fencem 3
; CHECK-NEXT:    or %s0, 0, %s2
; CHECK-NEXT:    b.l.t (, %s10)
  %result = atomicrmw udec_wrap ptr %ptr, i32 %val seq_cst
  ret i32 %result
}

define i64 @atomicrmw_udec_wrap_i64(ptr %ptr, i64 %val) {
; CHECK-LABEL: atomicrmw_udec_wrap_i64:
; CHECK:       # %bb.0:
; CHECK-NEXT:    fencem 3
; CHECK-NEXT:    ld %s2, (, %s0)
; CHECK-NEXT:  .LBB7_1: # %atomicrmw.start
; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
; CHECK-NEXT:    or %s3, 0, %s2
; CHECK-NEXT:    lea %s2, -1(, %s2)
; CHECK-NEXT:    cmpu.l %s4, %s3, %s1
; CHECK-NEXT:    cmov.l.gt %s2, %s1, %s4
; CHECK-NEXT:    cmov.l.eq %s2, %s1, %s3
; CHECK-NEXT:    cas.l %s2, (%s0), %s3
; CHECK-NEXT:    brne.l %s2, %s3, .LBB7_1
; CHECK-NEXT:  # %bb.2: # %atomicrmw.end
; CHECK-NEXT:    fencem 3
; CHECK-NEXT:    or %s0, 0, %s2
; CHECK-NEXT:    b.l.t (, %s10)
  %result = atomicrmw udec_wrap ptr %ptr, i64 %val seq_cst
  ret i64 %result
}
